namespace dw
{
	namespace graphics
	{
		template< typename T >
		inline Color< T >::Color(const T* data)
		{
			memcpy(this->data, data, sizeof (T) * 4);
		}

		template< typename T >
		inline Color< T >::Color(const Color& color) :
			r(color.r), g(color.g), b(color.b), a(color.a)
		{
		}
		
		template< typename T >
		inline Color< T >::Color(const T& r, const T& g, const T& b,const T& a) :
			r(r), g(g), b(b), a(a)
		{
		}

		template< typename T >
		inline Color< T >& Color< T >::operator=(const Color< T >& rhs)
		{
			this->r = rhs.r;
			this->g = rhs.g;
			this->b = rhs.b;
			this->a = rhs.a;
			return *this;
		}

		template< typename T >
		inline Color< T >& Color< T >::operator+=(const Color< T >& rhs)
		{
			this->r += rhs.r;
			this->g += rhs.g;
			this->b += rhs.b;
			this->a += rhs.a;
			return *this;
		}

		template< typename T >
		inline Color< T >& Color< T >::operator-=(const Color< T >& rhs)
		{
			this->r -= rhs.r;
			this->g -= rhs.g;
			this->b -= rhs.b;
			this->a -= rhs.a;
			return *this;
		}

		template< typename T >
		inline Color< T >& Color< T >::operator*=(const T& rhs)
		{
			this->r *= rhs;
			this->g *= rhs;
			this->b *= rhs;
			this->a *= rhs;
			return *this;
		}

		template< typename T >
		inline Color< T >& Color< T >::operator/=(const T& rhs)
		{
			this->r /= rhs;
			this->g /= rhs;
			this->b /= rhs;
			this->a /= rhs;
			return *this;
		}

		template< typename T >
		inline Color< T > operator+(const Color< T >& lhs, const Color< T >& rhs)
		{
			Color< T > nrv(lhs);
			nrv += rhs;
			return nrv;
		}

		template< typename T >
		inline Color< T > operator-(const Color< T >& lhs, const Color< T >& rhs)
		{
			Color< T > nrv(lhs);
			nrv += rhs;
			return nrv;
		}

		template< typename T >
		inline Color< T > operator*(const Color< T >& lhs, const T& rhs)
		{
			Color< T > nrv(lhs);
			nrv *= rhs;
			return nrv;
		}

		template< typename T >
		inline Color< T > operator*(const T& lhs, const Color< T >& rhs)
		{
			Color< T > nrv(rhs);
			nrv *= lhs;
			return nrv;
		}

		template< typename T >
		inline Color< T > operator/(const Color< T >& lhs, const T& rhs)
		{
			Color< T > nrv(lhs);
			nrv /= rhs;
			return nrv;
		}

		template< typename T >
		inline T Color< T >::diffuse(const T& kd, const maths::Vector< T, 3 >& N, const maths::Vector< T, 3 >& L)
		{
			return (kd * Vector< T, 3 >::dot(N, L));
		}

		template< typename T >
		inline T Color< T >::specular(const T& ks, 
			const maths::Vector< T, 3 >& R, 
			const maths::Vector< T, 3 >& V, 
			const T& n)
		{
			return (ks * std::pow< T >(Vector< T, 3 >::dot(R, V), n));
		}
	}
}
